Migrate web editor to react-native-enriched (web demo + UX fixes)#13
Merged
Conversation
Unify the comment composer on react-native-enriched across all platforms. Previously native used react-native-enriched (0.5.2) while web used Quill (react-quill-new); now that react-native-enriched 0.7.0 ships experimental web support via package `exports` conditions, both platforms share a single implementation. - Bump react-native-enriched 0.5.2 -> 0.7.0 (web support); make it a required (non-optional) peer at >=0.7.0. - Drop quill / react-quill-new from dev and peer dependencies. - Collapse comment-text-area.native.tsx + comment-text-area.web.tsx into a single comment-text-area.tsx. The same EnrichedTextInput API resolves to the native build on Metro and the web build on web bundlers, so web now gets the @mention popup that the Quill path was missing, plus inline-code formatting (toggleInlineCode) on both platforms. - example-web: pre-bundle react-native-enriched instead of quill, and add an exact-match react-native -> react-native-web alias so the enriched web build's bare `react-native` import (processColor) resolves during the production build. - Update the stale README (it still referenced the long-removed 10tap editor and react-native-webview) and the tests-ui enriched mock.
react-native-enriched 0.7.0's component reads `ref` as a prop (React 19 convention), so the web editor's imperative API never attached under the demo's React 18 - the toolbar, focus, setValue and image insert all no-op'd. Bump react/react-dom to 19 and react-native-web to 0.21 (0.19 calls the removed ReactDOM.findDOMNode under React 19; 0.20+ supports both). Also fix the Vite dev setup the bump and the enriched web build surfaced: - alias inline-style-prefixer's CJS `lib/*` deep paths to its ESM `es/*` build, and pre-bundle the CJS sub-entries react-native-web imports (styleq/transform-localize-style, fbjs/lib/invariant|warning, react-dom/client) so the browser doesn't choke on missing ESM exports. - dedupe react/react-dom so the SDK source (imported from ../src) shares the single React 19 instance instead of pulling its own copy.
Three issues surfaced testing the enriched web editor: - Editor only accepted clicks on the first line. tiptap's contenteditable (.ProseMirror) auto-sizes to its content inside the .eti-editor wrapper that gets our minHeight/flex, so the rest of the box was a dead div. Inject a tiny web-only rule to make the editor fill its wrapper. - Submitting a comment spun forever and made no request. submit()'s validation early-return never reset isReplySaving, and the guest name/email form never showed: needsAuth was `!currentUser && !!parentComment`, which only prompted on replies and treated the anon session (present from connect, no username/email) as logged in. Mirror the web widget: show the form when there's no authorized user or an anon session still owes an email; reset the spinner on early return; default the inputs to '' to avoid a controlled/uncontrolled warning. - @mention popup never appeared. detectMentionQuery bailed on the trailing newline that </p> produces in plain text, and the editor always wraps content in <p>...</p>. Strip trailing newlines before detecting. Extract detectMentionQuery/htmlToPlainText into a dependency-free module and add unit tests covering the real block-wrapped editor output.
The loading state early-returns only an absolutely-positioned overlay (inset:0). With nothing in flow its container collapses to 0 height, and on web (where the host #root is not always a flex container) a 0-height inset:0 box centers the large spinner on y=0 - i.e. half off the top of the screen. Fill via normal flow (flex + a minHeight floor) so it cannot collapse, and make the demo #root a flex container so the widget fills the viewport.
- Overlay the popup via a portal to document.body so it is not clipped by the scrollable comment list or painted under later comment rows. The composer lives inside react-native-web's virtualized list, whose transformed ancestor traps even position:fixed, so a web-only portal (mention-portal.web.tsx) is the reliable escape; native renders inline. - Keyboard nav: arrow keys move the highlight, Enter/Tab select, Esc dismisses. Intercepted on the editor wrapper in the capture phase because the enriched web build forwards keydown but always returns false to ProseMirror, so there is no supported way to cancel its handling. - Insert mentions inline with replaceActiveMention (splice at the located @query) rather than an end-anchored regex that missed block-wrapped HTML and appended onto a new line ("@A\n@name"). - The query is a single token (any whitespace ends it) and mentions commit with a non-breaking space, so typing past a completed mention no longer reopens the popup with "no matches". Detection/insertion live in a dependency-free mention-detection module with unit tests covering the real block-wrapped editor output.
On a successful post the API returns an authorized user carrying the email/username the guest entered. A second update block then re-applied a stale pre-merge snapshot, reverting currentUser to the anonymous session - so the name/email form stayed visible and the top bar never updated. Merge response.user into the session (matching the web widget) and read fresh store state when applying the sessionId so it no longer clobbers the merge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Unifies the comment composer on react-native-enriched across native and web, and fixes the issues found while testing the enriched editor in the browser demo.
Migration
comment-text-area.tsxfor both platforms).Web demo (example-web)
refas a prop, the React 19 convention; rnw 0.19 calls the removedReactDOM.findDOMNode).Fixes
response.userinto the session (and read fresh state for the sessionId) so the form hides and the top bar updates instead of reverting to the anon user.Tests
mention-detectionmodule with unit tests for the real block-wrapped editor output.